#pragma once 

#include "InetAddr.hpp"
#include <list>
#include <algorithm>
class UserStrategy
{
public:
    UserStrategy() = default;
    virtual void SendMessage(int fd,const string& message) = 0;
    virtual bool operator==(const InetAddr&) = 0;
    virtual string info() const = 0;
        
};

class User : public UserStrategy
{
public:
    User(const InetAddr& info):_info(info)
    {}
    User(const User& user):_info(user.Self())
    {}
    virtual void SendMessage(int fd,const string& message){
        ::sendto(fd,message.c_str(),message.size(),0,_info.Addr(),_info.Len());
    }
    virtual bool operator==(const InetAddr&self){
        //只要ip和端口一样就没问题
        return _info.NetAddr() == self.NetAddr();
    }

    const InetAddr& Self() const {
        return _info;
    }
    virtual string info() const {
        return _info.NetAddr();
    }
private:
    InetAddr _info;
};

class UserManger
{
public:
    UserManger(){
    }
    void AddUser(const User& user){
        LOG(INFO) << " void AddUser(const User& user)";
        LockGuard lock(_mutex);
        for (auto& x : _userlist){
            if ((*x) == user.Self()){
                LOG(INFO) << "用户"<< user.info() << "以存在";
                return;
            }
        }
        //开始添加
        _userlist.emplace_back(std::make_shared<User>(user));
    }

    void Delete(const User& user){
        LockGuard lock(_mutex);
        for (auto& x : _userlist){
            if ((*x) == user.Self()){
                LOG(DEBUG) << "删除用户" << user.info();
                //先把要删除的元素移动到list末尾, 返回对应元素的迭代器
                auto pos = remove_if(_userlist.begin(),_userlist.end(),[&](const std::shared_ptr<UserStrategy>&out){
                    return (*out) == user.Self();
                });
                //再删除
                _userlist.erase(pos);
                return;
            }
        }
        LOG(WARNING) << "用户" << user.info() << "不存在";
        return;
    }
    //发送消息到各个客户端
    void route(int fd,const string& message){
        LockGuard lock(_mutex);
        for (auto& x:_userlist){
            LOG(DEBUG) << "向" << x->info() << "发送" << message;
            x->SendMessage(fd,message);
        }
    }
    ~UserManger(){
        
    }    
private:
    std::list<std::shared_ptr<UserStrategy>> _userlist;
    //未来我们把所有的信息发送到对应的客户端中, 那么一定要办理_userlist(线程池)
    Mutex _mutex;
};